﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace POCOFirst
{
	public class Order
	{
		public Order(Customer customer)
		{
			this.Customer = customer;
			this.OrderDate = DateTime.Now;
			this.OrderNumber = 0;
		}

		public Customer Customer { get; private set; }
		public DateTime OrderDate { get; private set; }
		public int OrderNumber { get; private set; }

		public int TotalAmount { get; private set; }
		private IList<OrderLine> _orderLines = new List<OrderLine>();
	}

	public class OrderFactory
	{
		public static Order CreateOrder(Customer customer)
		{
			var o = new Order(customer);
			return o;
		}
	}

	public class OrderRepository : IRepository<Order>
	{
		private readonly ICollection<Order> _orders = new List<Order>();

		public IList<Order> GetListByParent(object parent)
		{
			var customer = parent as Customer;
			return this._orders.Where(o => o.Customer.Equals(customer)).ToList();
		}

		public Order GetEntityByIdentity(int id)
		{
			return this._orders.FirstOrDefault(o => o.OrderNumber.Equals(id));
		}

		public void AddEntity(Order entity)
		{
			var beforeAdd = this._orders.Count;
			this._orders.Add(entity);
			var afterAdd = this._orders.Count;

			// if it fails, the test will abort.
			Trace.Assert(afterAdd - beforeAdd == 1);
		}
	}

	public class CustomerRepository : IRepository<Customer>
	{
		private readonly ICollection<Customer> _customers = new List<Customer>();


		public IList<Customer> GetListByParent(object parent)
		{
			throw new NotImplementedException();
		}

		public Customer GetEntityByIdentity(int id)
		{
			return this._customers.FirstOrDefault(o => o.CustomerNumber.Equals(id));
		}

		public void AddEntity(Customer entity)
		{
			var beforeAdd = this._customers.Count;
			this._customers.Add(entity);
			var afterAdd = this._customers.Count;

			// if it fails, the test will abort.
			Trace.Assert(afterAdd - beforeAdd == 1);
		}
	}

	public class Customer
	{
		public int CustomerNumber { get; private set; }
		public bool Equals(Customer right)
		{
			return this.CustomerNumber.Equals(right.CustomerNumber);
		}
	}

	public interface IRepository<T>
	{
		IList<T> GetListByParent(object parent);
		T GetEntityByIdentity(int id);
		void AddEntity(T entity);
	}

	public class OrderLine
	{
		public Product Product { get; private set; }
		// keep a historic price of product?
		public decimal Price { get; private set; }
		public int NumberOfUnits { get; set; }

		public Order Order { get; set; }
		public decimal TotalAmount { get { return Price * NumberOfUnits; } }
	}

	public class Product
	{
		public string Name { get; set; }
		public decimal UnitPrice { get; set; }
		public string Descrition { get; set; }
	}
}